package com.dd.cloud.common.utils;

import com.dd.cloud.common.enums.ZkResponseEnum;
import com.dd.cloud.common.exception.ZekeAuthException;
import com.dd.cloud.common.exception.ZekeException;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Set;

/**
 * @author zk
 */
public class ValidatorUtils {
    private static class ValidatorFactoryInstance {
        private final static ValidatorFactory VF = Validation.buildDefaultValidatorFactory();
    }

    /**
     * 手动效验
     *
     * @param obj
     * @param cla
     */
    public static void verify(Object obj, Class<?> cla) {
        if (obj == null) {
            try {
                obj = cla.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
                //请求参数为空,实例化对象报错
                throw new ZekeException(400, "请求参数为空");
            }
        }
        Validator validator = ValidatorFactoryInstance.VF.getValidator();
        Set<ConstraintViolation<Object>> errorSet = validator.validate(obj);
        StringBuilder sb = new StringBuilder();
        for (ConstraintViolation<Object> item : errorSet) {
            sb.append(item.getMessage());
            sb.append(",");
        }
        if (sb.length() != 0) {
            sb.deleteCharAt(sb.length() - 1);
            throw new ZekeException(400, sb.toString());
        }
    }

    /**
     * 手动效验 增加分组验证
     *
     * @param obj
     * @param cla
     */
    public static void verifyGroup(Object obj, Class<?> cla, Class<?>... groups) {
        if (obj == null) {
            try {
                obj = cla.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
                //请求参数为空,实例化对象报错
                throw new ZekeException(400, "请求参数为空");
            }
        }
        Validator validator = ValidatorFactoryInstance.VF.getValidator();
        Set<ConstraintViolation<Object>> errorSet = validator.validate(obj, groups);
        StringBuilder sb = new StringBuilder();
        for (ConstraintViolation<Object> item : errorSet) {
            sb.append(item.getMessage());
            sb.append(",");
        }
        if (sb.length() != 0) {
            sb.deleteCharAt(sb.length() - 1);
            throw new ZekeException(400, sb.toString());
        }
    }

    /**
     * 手动效验 不抛异常
     *
     * @param obj
     * @param cla
     */
    public static String verifyStr(Object obj, Class<?> cla) {
        if (obj == null) {
            try {
                obj = cla.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
                //请求参数为空,实例化对象报错
                return "请求参数为空";
            }
        }
        Validator validator = ValidatorFactoryInstance.VF.getValidator();
        Set<ConstraintViolation<Object>> errorSet = validator.validate(obj);
        StringBuilder sb = new StringBuilder();
        for (ConstraintViolation<Object> item : errorSet) {
            sb.append(item.getMessage());
            sb.append(",");
        }
        if (sb.length() != 0) {
            sb.deleteCharAt(sb.length() - 1);
            return sb.toString();
        }
        return null;
    }

    /**
     * 手动效验
     *
     * @param obj
     * @param cla
     */
    public static void verifyAuth(Object obj, Class<?> cla) {
        if (obj == null) {
            try {
                obj = cla.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
                //请求参数为空,实例化对象报错
                throw new ZekeAuthException(400, "请求参数为空");
            }
        }
        Validator validator = ValidatorFactoryInstance.VF.getValidator();
        Set<ConstraintViolation<Object>> errorSet = validator.validate(obj);
        StringBuilder sb = new StringBuilder();
        for (ConstraintViolation<Object> item : errorSet) {
            sb.append(item.getMessage());
            sb.append(",");
        }
        if (sb.length() != 0) {
            sb.deleteCharAt(sb.length() - 1);
            throw new ZekeAuthException(ZkResponseEnum.REQUEST_ERROR.getCode(), sb.toString());
        }
    }
}
